﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace T4Airline.Website
{
	public static class FAAFlightData
	{
		// Finds the airport departure delay from the FAA City Pair Analysis Report.
		public static int DepartureDelay(string departureCode, string arrivalCode)
		{

			//DataClasses1DataContext db = new DataClasses1DataContext();
			using (var db = new T4Airline.Entities.team4AirlineEntities())
			{

				var departureDelayQuery = (from faa in db.FAACityPairAnalysis
										   where faa.DepartureCode == departureCode
										   where faa.ArrivalCode == arrivalCode
										   select new { faa.AirportDepartureDelay }).SingleOrDefault();

				int departureDelay = (int)departureDelayQuery.AirportDepartureDelay;

				//db.Dispose();

				return departureDelay;
			}
		}

		// Finds the airpots arrival delay from the FAA City Pair Analysis Report.
		public static int ArrivalDelay(string departureCode, string arrivalCode)
		{

			using (var db = new T4Airline.Entities.team4AirlineEntities())
			{

				var arrivalDelayQuery = (from faa in db.FAACityPairAnalysis
										 where faa.DepartureCode == departureCode
										 where faa.ArrivalCode == arrivalCode
										 select new { faa.GateArrivalDelay }).SingleOrDefault();

				int arrivalDelay = (int)arrivalDelayQuery.GateArrivalDelay;

				//db.Dispose();

				return arrivalDelay;
			}
		}

		// Finds the percent of flights arriving late for more than 15 minutes for an airport
		// due to "extreme" weather as the only factor.
		public static double ExtremeWeatherOnlyFactorYearlyPercentDelay(string airportCode)
		{
			using (var db = new T4Airline.Entities.team4AirlineEntities())
			{

				var percentOfOnTimeFlights = (from faa in db.FAAAirportDelays
											  where faa.AirportCode == airportCode
											  select new { faa.WeatherFactorPercent }).SingleOrDefault();


				double percentWeatherDelay = 100 - (double)percentOfOnTimeFlights.WeatherFactorPercent;



				//db.Dispose();

				return percentWeatherDelay;
			}
		}


		// Finds the percent of flights arriving late for more than 15 minutes for an airport
		// due to weather as the only factor as stated by the National Aviation System (NAS).
		// Note that the NAS 'weather' delay is 62.23% of the delays; other factors are 'Volume (31.2%),
		// 'Closed Runway'  and 'Other'.
		public static double NasWeatherOnlyFactorYearlyPercentDelay(string airportCode)
		{
			using (var db = new T4Airline.Entities.team4AirlineEntities())
			{

				var percentaNasOnTimeFlights = (from faa in db.FAAAirportDelays
												where faa.AirportCode == airportCode
												select new { faa.NasCausePercent }).SingleOrDefault();

				double percentNasWeatherDelay = (100 - (double)percentaNasOnTimeFlights.NasCausePercent) * .6223;

				//db.Dispose();

				return percentNasWeatherDelay;
			}
		}


		// Finds the average minutes delayted due to weather for an airline in specific airports
		public static int AirlineWeatherDelayMinutes(string airlineCode, string airportCode)
		{
			using (var db = new T4Airline.Entities.team4AirlineEntities())
			{

				var airlineWeatherDelayMinutes = (from faa in db.DelaysByAirlines
												  where faa.airport == airportCode
												  where faa.carrier == airlineCode
												  select new { faa.weather_delay, faa.nas_delay, faa.arr_delay }).FirstOrDefault();  // note: database may have these values repeated

				//var airlineNasDelayMinutes = (from faa in db.DelaysByAirlines
				//                          where faa.airport == airportCode
				//                          where faa.carrier == airlineCode
				//                              select new { faa.nas_delay }).FirstOrDefault();                       
				int delayMinutes = 0;
				if (airlineWeatherDelayMinutes != null)
				{
					delayMinutes = (int)(airlineWeatherDelayMinutes.weather_delay + airlineWeatherDelayMinutes.nas_delay * 0.6223 / airlineWeatherDelayMinutes.arr_delay);
				}
				//db.Dispose();

				return delayMinutes;
			}
		}

		public static double FlightDepartureDelayPercentChance(int departureAirportID, int arrivalAirportID, int airlineID, int windspeed =0)
		{
				using (var db = new T4Airline.Entities.team4AirlineEntities())
			{
			var flightDelays = (from x in db.FAACityPairAnalysis where x.DepartureAirportID == departureAirportID && x.ArrivalAirportID == arrivalAirportID select x).FirstOrDefault();
					double delayChance =0.0;

					var airlineDelays = (from x in db.DelaysByAirlines where x.AirlineID == airlineID && x.AirportID == departureAirportID select x).ToList();

					double flightsLate = airlineDelays.Sum(x => x.arr_del15) ?? 0;
					double totalFlights = airlineDelays.Sum(x => x.arr_flights) ?? 1;

					double airlineDelayPercentage = 0.0;
					if(totalFlights != 0.0)
						airlineDelayPercentage = flightsLate / totalFlights;

					if(flightDelays != null)
					{
						delayChance= (100.0 - (flightDelays.OnTimeAirportDepartures ?? 100.0)) / 100;				
					}
					return ((airlineDelayPercentage + delayChance + (windspeed /200)) / 3);
		
				}
		}

		public static double FlightDepartureDelayPercentChance(int departureAirportID, int arrivalAirportID, int airlineID,  int connectingAirportID, int windspeed = 0)
		{
			using (var db = new T4Airline.Entities.team4AirlineEntities())
			{
				var flightDelays1 = (from x in db.FAACityPairAnalysis where x.DepartureAirportID == departureAirportID && x.ArrivalAirportID == connectingAirportID select x).FirstOrDefault();
				var flightDelays2 = (from x in db.FAACityPairAnalysis where x.DepartureAirportID == connectingAirportID && x.ArrivalAirportID == arrivalAirportID select x).FirstOrDefault();

				double delayChance = 0.0;

				var airlineDelays = (from x in db.DelaysByAirlines where x.AirlineID == airlineID && x.AirportID == departureAirportID select x).ToList();

				double flightsLate = airlineDelays.Sum(x => x.arr_del15) ?? 0;
				double totalFlights = airlineDelays.Sum(x => x.arr_flights) ?? 1;

				double airlineDelayPercentage = 0.0;
				if (totalFlights != 0.0)
					airlineDelayPercentage = flightsLate / totalFlights;

				if (flightDelays1 != null)
				{
					delayChance = (100.0 - (flightDelays1.OnTimeAirportDepartures ?? 100.0)) / 100;
				}
				if (flightDelays2 != null)
				{
					delayChance = (delayChance + (100.0 - (flightDelays2.OnTimeAirportDepartures ?? 100.0)) / 100)/2;
				}
				return ((airlineDelayPercentage + delayChance + (windspeed / 200)) / 3);

			}
		}

		public static double FlightArrivalDelayPercentChance(int departureAirportID, int arrivalAirportID, int airlineID, int windspeed = 0)
		{
			using (var db = new T4Airline.Entities.team4AirlineEntities())
			{
				var flightDelays = (from x in db.FAACityPairAnalysis where x.DepartureAirportID == departureAirportID && x.ArrivalAirportID == arrivalAirportID select x).FirstOrDefault();
				double delayChance = 0.0;

				var airlineDelays = (from x in db.DelaysByAirlines where x.AirlineID == airlineID && x.AirportID == arrivalAirportID select x).ToList();

				double flightsLate = airlineDelays.Sum(x => x.arr_del15) ?? 0;
				double totalFlights = airlineDelays.Sum(x => x.arr_flights) ?? 1;
				double airlineDelayPercentage = 0.0;
				if (totalFlights != 0.0)
					airlineDelayPercentage = flightsLate / totalFlights;

				if (flightDelays != null)
				{

					delayChance = (100.0 - (flightDelays.OnTimeGateArrivals ?? 100.0)) / 100;
				}
				return ((airlineDelayPercentage + delayChance + (windspeed / 200)) / 3);
			}
		}


		public static List<Entities.Airport> GetConnectingAirports(int departureAirportID, int arrivalAirportID)
	{
	
		using (var db = new T4Airline.Entities.team4AirlineEntities())
			{

				var departureAirportConnections = (from x in db.Routes where x.OriginAirportID == departureAirportID select x.DestinationAirportID).Distinct().ToList();

				var arrivalAirportConnections = (from x in db.Routes where x.DestinationAirportID == arrivalAirportID && departureAirportConnections.Contains(x.OriginAirportID) select x.DepartureAirport).Distinct().ToList();

				return arrivalAirportConnections;

			

			}
}


	}

}
